#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>

/*
 * 可靠信号与不可靠信号
 */

#if 0

不可靠信号： 也称为非实时信号，不支持排队，信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次，信号值取值区间为1~31。
可靠信号： 也称为实时信号，支持排队, 信号不会丢失, 发多少次, 就可以收到多少次. 信号值取值区间为32~64。

/* 实时信号与不可靠信号的区别 */
主要就是实时信号支持排队不会丢失。（实时信号还有一个特点，即到达的顺序是可以保证的）


通过系统调用，发送signal信号：kill()，raise()，sigqueue()，alarm()，setitimer()，abort()


/* 在队列中向指定进程发送一个信号和数据 */
/* 新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用 */
int sigqueue(pid_t pid, int sig, const union sigval value);

    sigqueue的第一个参数是指定接收信号的进程id，
    第二个参数确定即将发送的信号，
    第三个参数是一个联合数据结构union sigval，指定了信号传递的参数，即通常所说的4字节值。

    成功返回0,失败返回-1 

typedef union sigval
{ 
    int sival_int; 
    void *sival_ptr; 
}sigval_t; 
 

sigqueue()比kill()传递了更多的附加信息，但sigqueue()只能向一个进程发送信号，而不能发送信号给一个进程组。
 


#endif


#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)



int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "Usage %s pid\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    pid_t pid = atoi(argv[1]); //字符串转换为整数
    union sigval val;
    val.sival_int = 100;
    sigqueue(pid, SIGINT, val); // 不可靠信号不会排队，即会丢失
    sigqueue(pid, SIGINT, val);
    sigqueue(pid, SIGINT, val);
    sigqueue(pid, SIGRTMIN, val); //实时信号会排队，即不会丢失
    sigqueue(pid, SIGRTMIN, val);
    sigqueue(pid, SIGRTMIN, val);
    sleep(3);
    kill(pid, SIGUSR1);

    return 0;

}

#if 0


#endif
